/******************************************************************************************
文件名：ringbuffer.c
作者：狼狼    版本：V1.0    创建日期：2021.8.1
文件描述：
    基于堆区的环形缓冲区。
历史修改记录：
1. 2021-8-1:V1.0 狼狼
创建。
2. 2021-8-31:V1.0 狼狼
修复get_data_point、update_data_point和wait_for_data方法函数中对缓冲区操作的错误。
3. 2022-5-11:V1.0 狼狼
代码公开。
******************************************************************************************/
//+------------------------------------------------------------------------------------------+
//|                                            前言
//+------------------------------------------------------------------------------------------+
//|      很多情况下程序需要一个应用层缓冲区来缓存数据，特别是在生产者-消费者模型中。缓冲区通常
//|  较大，因而使用从堆区开辟的空间，并提供更多可控制的接口和操作。
//+------------------------------------------------------------------------------------------+
//|                                          文件说明
//+------------------------------------------------------------------------------------------+
//|      本程序实现了一个简单的基于堆区内存的基本环形缓冲区，对外提供了基本数据读写、清空、等
//|  待和存储情况查询等接口。为了减少数据在存取时的拷贝次数，缓冲区提供了一种基于读指针+长度+
//|  更新函数的组合操作方式，将内部的读指针直接暴露给上层应用，使上层程序可直接访问缓冲区空间
//|  中的内容，从而减少了一次拷贝。
//|      [程序员说]我们是否可以保留更加常规的方式，为缓冲区增加一个get_data接口呢？当然可以，
//|  但是在目前还没实现它（因为暂时用不到），你可以参考add_data的方法去实现这个接口。最后，记
//|  得进行测试！
//+------------------------------------------------------------------------------------------+
//|                                         头文件包含
//+------------------------------------------------------------------------------------------+
/*|*/#include <stdio.h>
/*|*/#include <string.h>
/*|*/#include <stdlib.h>
//|
/*|*/#include "ringbuffer.h"
/*|*/#include "project_debug.h"
//+------------------------------------------------------------------------------------------+
//|  函数名称：add_data
//|  功能描述：向缓冲区中添加数据
//|  参数说明：指向缓冲区对象结构的指针，指向源数据的指针，数据长度
//|  返回值说明：成功返回实际拷贝的数据长度，失败返回错误码（负值）
//|  备注：注意：若返回0表示数据拷贝长度为0。
//+------------------------------------------------------------------------------------------+
static int add_data(struct ring_buffer * const buf, const uint8_t *pdata, uint32_t len)
{
    uint32_t write_to_do = 0;
    
    /* 参数检查 */
    if(buf == NULL || pdata == NULL)
    {
        OUTPUT("[RINGBUF-ERROR]Pointer is NULL!\n");
        return RINGBUF_ERROR_ILLEGAL_PARAM;
    }
    
    if(len == 0)
    {
        OUTPUT("[RINGBUF-ERROR]Data length is 0!\n");
        return RINGBUF_ERROR_ILLEGAL_PARAM;
    }
    
    /* 目标缓冲区状态检查 */
    if(buf->state != RINGBUF_STAT_OK)
    {
        OUTPUT("[RINGBUF-ERROR]The current state[%d] does not support operation[add_data]!\n", buf->state);
        return RINGBUF_ERROR_UNEXPECT_STATE;
    }
    
    /* 获取缓冲区互斥锁并执行数据拷贝 */
    // ----------------------------------------
    // [说明]将互斥锁操作放在此处可使本函数在多
    //       个线程同时调用时保证数据的完整性。
    // ----------------------------------------
    pthread_mutex_lock(&buf->mutex);
    
    /* 防止超界写入 */
#ifdef RINGBUF_SWITCH_ADD_DATA_ALL
    if(len > buf->unused_space)
    {
        OUTPUT("[RINGBUF-DEBUG]The buffer does not have enough space to store data!\n");
        pthread_mutex_unlock(&buf->mutex);
        return RINGBUF_ERROR_UNEXPECT_DATA_LENGTH;
    }
#else
    if(len > buf->unused_space)
    {
        write_to_do = buf->unused_space;
    }
#endif
    write_to_do = len;
    if(write_to_do == 0)
    {
        // 此时无需执行真正意义上的拷贝
        pthread_mutex_unlock(&buf->mutex);
        return 0;
    }

    if((buf->capacity - (buf->pwrite_pos - buf->pbuf)) >= write_to_do)
    {
        // 从写指针位置直接写入，不需考虑缓冲区末尾边界处的分割
        memcpy(buf->pwrite_pos, pdata, write_to_do);
        buf->used_space   += write_to_do;
        buf->unused_space -= write_to_do;
        buf->pwrite_pos   += write_to_do;
        if(buf->pwrite_pos >= (buf->pbuf + buf->capacity))
        {
            buf->pwrite_pos = buf->pbuf;// 写指针超界重置
        }
    }
    else
    {
        // 分两次写入
        uint32_t write_step_1 = buf->capacity - (buf->pwrite_pos - buf->pbuf);
        uint32_t write_step_2 = write_to_do - write_step_1;
        
        // 1.从当前写指针位置写到缓冲区末尾
        memcpy(buf->pwrite_pos, pdata, write_step_1);
        // ----------------------------------------
        // [说明]这里直接对写指针重置，因为前面的写
        //       入已经覆盖了原写指针指向位置直至缓
        //       冲区内存末尾的空间。
        // ----------------------------------------
        buf->pwrite_pos = buf->pbuf;
        
        // 2.从起始位置写入剩余字节
        memcpy(buf->pwrite_pos, pdata + write_step_1, write_step_2);
        
        // 3.更新缓冲区信息
        buf->used_space   += write_to_do;
        buf->unused_space -= write_to_do;
        buf->pwrite_pos   += write_step_2;
    }
    
    pthread_mutex_unlock(&buf->mutex);
    
    /* 解除可能存在的等待线程阻塞 */
    pthread_cond_signal(&buf->cond);
    
    return write_to_do;
}

//+------------------------------------------------------------------------------------------+
//|  函数名称：get_data_len
//|  功能描述：配合数据指针获取函数，获取当前数据指针指向的有效数据长度
//|  参数说明：指向缓冲区对象结构的指针，数据长度输出指针
//|  返回值说明：成功返回RINGBUF_SUCCESS，失败返回错误码（负值）
//|  备注：
//+------------------------------------------------------------------------------------------+
static int get_data_len(struct ring_buffer * const buf, uint32_t *plen)
{
    /* 参数检查 */
    if(buf == NULL || plen == NULL)
    {
        OUTPUT("[RINGBUF-ERROR]Pointer is NULL!\n");
        return RINGBUF_ERROR_ILLEGAL_PARAM;
    }
    
    /* 目标缓冲区状态检查 */
    if(buf->state != RINGBUF_STAT_OK)
    {
        OUTPUT("[RINGBUF-ERROR]The current state[%d] does not support operation[get_data_len]!\n", buf->state);
        return RINGBUF_ERROR_UNEXPECT_STATE;
    }
    
    /* 空间占用分析 */
    pthread_mutex_lock(&buf->mutex);
    
    // ----------------------------------------
    // [说明]由于堆区空间并非真正的环形缓冲，如
    //       果使用读指针引出的方式，必须保证其
    //       中的数据是连续的，因此当数据跨结尾
    //       边界存放，则需要分批访问。
    // ----------------------------------------
    uint32_t remain_len = buf->capacity - (buf->pread_pos - buf->pbuf);
    if(buf->used_space <= remain_len)
    {
        *plen = buf->used_space;
    }
    else
    {
        *plen = remain_len;
    }
    
    pthread_mutex_unlock(&buf->mutex);
    
    return RINGBUF_SUCCESS;
}

//+------------------------------------------------------------------------------------------+
//|  函数名称：get_data_point
//|  功能描述：配合有效数据长度获取函数，获取当前数据首地址指针
//|  参数说明：指向缓冲区对象结构的指针，指向数据首地址指针的指针
//|  返回值说明：成功返回RINGBUF_SUCCESS，失败返回错误码（负值）
//|  备注：读指针指向的位置只有在更新数据指针时才会变化，因此此处无需执行互斥操作。
//+------------------------------------------------------------------------------------------+
static int get_data_point(struct ring_buffer * const buf, uint8_t **ppdata)
{
    /* 参数检查 */
    if(buf == NULL)
    {
        OUTPUT("[RINGBUF-ERROR]RingBuffer pointer is NULL!\n");
        return RINGBUF_ERROR_ILLEGAL_PARAM;
    }
    if(ppdata == NULL)
    {
        OUTPUT("[RINGBUF-ERROR]Level 2 pointer can't be NULL!\n");
        return RINGBUF_ERROR_ILLEGAL_PARAM;
    }
    if(*ppdata != NULL)
    {
        OUTPUT("[RINGBUF-ERROR]Level 1 pointer must be NULL!\n");
        return RINGBUF_ERROR_ILLEGAL_PARAM;
    }
    
    /* 目标缓冲区状态检查 */
    if(buf->state != RINGBUF_STAT_OK)
    {
        OUTPUT("[RINGBUF-ERROR]The current state[%d] does not support operation[get_data_point]!\n", buf->state);
        return RINGBUF_ERROR_UNEXPECT_STATE;
    }
    
    /* 将缓冲区读指针位置引出 */
    // ----------------------------------------
    // [说明]读指针位置的正确性由其更新函数负责
    // ----------------------------------------
    *ppdata = buf->pread_pos;
    
    return RINGBUF_SUCCESS;
}

//+------------------------------------------------------------------------------------------+
//|  函数名称：update_data_point
//|  功能描述：配合数据长度获取函数，更新读数据指针位置
//|  参数说明：指向缓冲区对象结构的指针，更新长度
//|  返回值说明：成功返回RINGBUF_SUCCESS，失败返回错误码（负值）
//|  备注：
//+------------------------------------------------------------------------------------------+
static int update_data_point(struct ring_buffer * const buf, uint32_t len)
{
    /* 参数检查 */
    if(buf == NULL)
    {
        OUTPUT("[RINGBUF-ERROR]Pointer is NULL!\n");
        return RINGBUF_ERROR_ILLEGAL_PARAM;
    }
    
    /* 目标缓冲区状态检查 */
    if(buf->state != RINGBUF_STAT_OK)
    {
        OUTPUT("[RINGBUF-ERROR]The current state[%d] does not support operation[update_data_point]!\n", buf->state);
        return RINGBUF_ERROR_UNEXPECT_STATE;
    }
    
    /* 防止超界更新 */
    pthread_mutex_lock(&buf->mutex);
    
    if(len > buf->used_space)
    {
        OUTPUT("[RINGBUF-ERROR]The data to be updated is too long!-1\n");
        pthread_mutex_unlock(&buf->mutex);
        return RINGBUF_ERROR_UNEXPECT_UPDATE_LENGTH;
    }
    
    // ----------------------------------------
    // [说明]此处适配可读数据长度获取函数的特性
    // ----------------------------------------
    uint32_t remain_len = buf->capacity - (buf->pread_pos - buf->pbuf);
    if(len > remain_len)
    {
        OUTPUT("[RINGBUF-ERROR]The data to be updated is too long!-2\n");
        pthread_mutex_unlock(&buf->mutex);
        return RINGBUF_ERROR_UNEXPECT_UPDATE_LENGTH;
    }
    
    /* 更新缓冲区信息 */
    buf->used_space   -= len;
    buf->unused_space += len;
    buf->pread_pos    += len;
    if(buf->pread_pos >= (buf->pbuf + buf->capacity))
    {
        buf->pread_pos = buf->pbuf;// 读指针超界重置
    }
    
    pthread_mutex_unlock(&buf->mutex);
    
    return RINGBUF_SUCCESS;
}

//+------------------------------------------------------------------------------------------+
//|  函数名称：wait_for_data
//|  功能描述：等待缓冲区非空
//|  参数说明：指向缓冲区对象结构的指针
//|  返回值说明：若缓冲区中有数据则返回RINGBUF_SUCCESS，无数据则等待，失败返回错误码（负值）
//|  备注：
//+------------------------------------------------------------------------------------------+
static int wait_for_data(struct ring_buffer * const buf)
{
    /* 参数检查 */
    if(buf == NULL)
    {
        OUTPUT("[RINGBUF-ERROR]Pointer is NULL!\n");
        return RINGBUF_ERROR_ILLEGAL_PARAM;
    }
    
    /* 目标缓冲区状态检查 */
    if(buf->state != RINGBUF_STAT_OK)
    {
        OUTPUT("[RINGBUF-ERROR]The current state[%d] does not support operation[wait_for_data]!\n", buf->state);
        return RINGBUF_ERROR_UNEXPECT_STATE;
    }
    
    pthread_mutex_lock(&buf->mutex);
    if(buf->used_space != 0)
    {
        pthread_mutex_unlock(&buf->mutex);
        return RINGBUF_SUCCESS;
    }
    pthread_mutex_unlock(&buf->mutex);
    
    /* 阻塞等待条件变量满足 */
    pthread_mutex_lock(&buf->cond_mutex);
    pthread_cond_wait(&buf->cond, &buf->cond_mutex);
    pthread_mutex_unlock(&buf->cond_mutex);
    
    /* 目标缓冲区状态检查（二次确认） */
    if(buf->state != RINGBUF_STAT_OK)
    {
        OUTPUT("[RINGBUF-DEBUG]The ring buffer state[%d] changed while waiting condition[wait_for_data]!\n", buf->state);
        return RINGBUF_ERROR_UNEXPECT_STATE;
    }
    
    return RINGBUF_SUCCESS;
}

//+------------------------------------------------------------------------------------------+
//|  函数名称：switch_to_disable
//|  功能描述：修改缓冲区状态为RINGBUF_STAT_DISABILED
//|  参数说明：指向缓冲区对象结构的指针
//|  返回值说明：成功返回RINGBUF_SUCCESS，失败返回错误码（负值）
//|  备注：设计用于上层应用退出或异常情况时对缓冲区的紧急停用操作。
//+------------------------------------------------------------------------------------------+
static int switch_to_disable(struct ring_buffer * const buf)
{
    /* 参数检查 */
    if(buf == NULL)
    {
        OUTPUT("[RINGBUF-ERROR]Pointer is NULL!\n");
        return RINGBUF_ERROR_ILLEGAL_PARAM;
    }
    
    /* 目标缓冲区状态检查 */
    if(buf->state == RINGBUF_STAT_DISABILED)
    {
        OUTPUT("[RINGBUF-INFO]The ring buffer has already been disabled[switch_to_disable]!\n");
        return RINGBUF_SUCCESS;
    }
    else if(buf->state != RINGBUF_STAT_OK)
    {
        OUTPUT("[RINGBUF-ERROR]The current state[%d] does not support operation[switch_to_disable]!\n", buf->state);
        return RINGBUF_ERROR_UNEXPECT_STATE;
    }
    
    /* 获取缓冲区互斥锁 */
    // ----------------------------------------
    // [说明]这里获取缓冲区互斥锁的目的是：确保
    //       本次修改能同步应用到各线程下一次对
    //       缓冲区的访问。
    // ----------------------------------------
    pthread_mutex_lock(&buf->mutex);
    buf->state = RINGBUF_STAT_DISABILED;
    pthread_mutex_unlock(&buf->mutex);
    
    /* 解除可能存在的等待线程阻塞 */
    pthread_cond_signal(&buf->cond);
    
    return RINGBUF_SUCCESS;
}

//+------------------------------------------------------------------------------------------+
//|  函数名称：switch_to_enable
//|  功能描述：修改缓冲区状态为RINGBUF_STAT_OK
//|  参数说明：指向缓冲区对象结构的指针
//|  返回值说明：成功返回RINGBUF_SUCCESS，失败返回错误码（负值）
//|  备注：设计用于上层应用清空缓冲区后重新启用缓冲区。
//+------------------------------------------------------------------------------------------+
static int switch_to_enable(struct ring_buffer * const buf)
{
    /* 参数检查 */
    if(buf == NULL)
    {
        OUTPUT("[RINGBUF-ERROR]Pointer is NULL!\n");
        return RINGBUF_ERROR_ILLEGAL_PARAM;
    }
    
    /* 目标缓冲区状态检查 */
    if(buf->state == RINGBUF_STAT_OK)
    {
        OUTPUT("[RINGBUF-INFO]The ring buffer has already been enabled[switch_to_enable]!\n");
        return RINGBUF_SUCCESS;
    }
    else if(buf->state != RINGBUF_STAT_DISABILED)
    {
        OUTPUT("[RINGBUF-ERROR]The current state[%d] does not support operation[switch_to_enable]!\n", buf->state);
        return RINGBUF_ERROR_UNEXPECT_STATE;
    }
    
    /* 获取缓冲区互斥锁 */
    // ----------------------------------------
    // [说明]这里获取缓冲区互斥锁的目的是：确保
    //       本次修改能同步应用到各线程下一次对
    //       缓冲区的访问。
    // ----------------------------------------
    pthread_mutex_lock(&buf->mutex);
    buf->state = RINGBUF_STAT_OK;
    pthread_mutex_unlock(&buf->mutex);
    
    return RINGBUF_SUCCESS;
}

//+------------------------------------------------------------------------------------------+
//|  函数名称：clear
//|  功能描述：清空缓冲区
//|  参数说明：指向缓冲区对象结构的指针
//|  返回值说明：成功返回RINGBUF_SUCCESS，失败返回错误码（负值）
//|  备注：
//+------------------------------------------------------------------------------------------+
static int clear(struct ring_buffer * const buf)
{
    /* 参数检查 */
    if(buf == NULL)
    {
        OUTPUT("[RINGBUF-ERROR]Pointer is NULL!\n");
        return RINGBUF_ERROR_ILLEGAL_PARAM;
    }
    
    /* 目标缓冲区状态检查（清空操作必须在禁用缓冲区的情况下进行） */
    if(buf->state != RINGBUF_STAT_DISABILED)
    {
        OUTPUT("[RINGBUF-ERROR]The current state[%d] does not support operation[clear]!\n", buf->state);
        return RINGBUF_ERROR_UNEXPECT_STATE;
    }
    
    /* 获取缓冲区互斥锁并执行数据清空 */
    pthread_mutex_lock(&buf->mutex);
    
    buf->pread_pos    = buf->pbuf;
    buf->pwrite_pos   = buf->pbuf;
    buf->used_space   = 0;
    buf->unused_space = buf->capacity;
    memset(buf->pbuf, 0, buf->capacity);
    
    pthread_mutex_unlock(&buf->mutex);
    
    return RINGBUF_SUCCESS;
}

//+------------------------------------------------------------------------------------------+
//|  函数名称：get_used_space
//|  功能描述：获取缓冲区中当前已用空间大小（单位字节）
//|  参数说明：指向缓冲区对象结构的指针
//|  返回值说明：成功返回RINGBUF_SUCCESS，失败返回错误码（负值）
//|  备注：
//+------------------------------------------------------------------------------------------+
static int get_used_space(struct ring_buffer * const buf, uint32_t *plen)
{
    /* 参数检查 */
    if(buf == NULL || plen == NULL)
    {
        OUTPUT("[RINGBUF-ERROR]Pointer is NULL!\n");
        return RINGBUF_ERROR_ILLEGAL_PARAM;
    }
    
    /* 目标缓冲区状态检查 */
    if(buf->state != RINGBUF_STAT_OK)
    {
        OUTPUT("[RINGBUF-ERROR]The current state[%d] does not support operation[get_used_space]!\n", buf->state);
        return RINGBUF_ERROR_UNEXPECT_STATE;
    }
    
    /* 缓冲区操作 */
    pthread_mutex_lock(&buf->mutex);
    *plen = buf->used_space;
    pthread_mutex_unlock(&buf->mutex);
    
    return RINGBUF_SUCCESS;
}

//+------------------------------------------------------------------------------------------+
//|  函数名称：get_unused_space
//|  功能描述：获取缓冲区中当前剩余空间大小（单位字节）
//|  参数说明：指向缓冲区对象结构的指针
//|  返回值说明：成功返回RINGBUF_SUCCESS，失败返回错误码（负值）
//|  备注：
//+------------------------------------------------------------------------------------------+
static int get_unused_space(struct ring_buffer * const buf, uint32_t *plen)
{
    /* 参数检查 */
    if(buf == NULL || plen == NULL)
    {
        OUTPUT("[RINGBUF-ERROR]Pointer is NULL!\n");
        return RINGBUF_ERROR_ILLEGAL_PARAM;
    }
    
    /* 目标缓冲区状态检查 */
    if(buf->state != RINGBUF_STAT_OK)
    {
        OUTPUT("[RINGBUF-ERROR]The current state[%d] does not support operation[get_unused_space]!\n", buf->state);
        return RINGBUF_ERROR_UNEXPECT_STATE;
    }
    
    /* 缓冲区操作 */
    pthread_mutex_lock(&buf->mutex);
    *plen = buf->unused_space;
    pthread_mutex_unlock(&buf->mutex);
    
    return RINGBUF_SUCCESS;
}

//+------------------------------------------------------------------------------------------+
//|  函数名称：ring_buffer_create
//|  功能描述：初始化一个缓冲区对象结构，为其在堆上申请内存空间
//|  参数说明：指向缓冲区对象结构的指针，缓冲区大小（字节）
//|  返回值说明：成功返回RINGBUF_SUCCESS
//|  备注：
//+------------------------------------------------------------------------------------------+
int ring_buffer_create(ST_RING_BUFFER *buf, uint32_t capacity)
{
    uint8_t *ptmp = NULL;
    
    /* 目标缓冲区状态检查 */
    if(buf == NULL)
    {
        OUTPUT("[RINGBUF-ERROR]Pointer is NULL!\n");
        return RINGBUF_ERROR_ILLEGAL_PARAM;
    }
    if(buf->state != RINGBUF_STAT_INIT)
    {
        OUTPUT("[RINGBUF-ERROR]The current state[%d] does not support operation[create]!\n", buf->state);
        return RINGBUF_ERROR_UNEXPECT_STATE;
    }
    
    /* 参数检查 */
    if(capacity == 0)
    {
        OUTPUT("[RINGBUF-ERROR]The requested space is 0!\n");
        return RINGBUF_ERROR_ILLEGAL_PARAM;
    }
    
    /* 尝试申请堆内存 */
    ptmp = malloc(capacity);
    if(ptmp == NULL)
    {
        OUTPUT("[RINGBUF-ERROR]Malloc[%d] failed!\n", capacity);
        return RINGBUF_ERROR_MALLOC;
    }
    
    /* 更新缓冲区对象结构 */
    memset(buf, 0, sizeof(ST_RING_BUFFER));
    
    if(pthread_mutex_init(&buf->mutex, NULL) != 0)
    {
        OUTPUT("[RINGBUF-ERROR]Failed to init mutex!\n");
        free(ptmp);
        return RINGBUF_ERROR_METUX;
    }
    if(pthread_mutex_init(&buf->cond_mutex, NULL) != 0)
    {
        OUTPUT("[RINGBUF-ERROR]Failed to init cond_mutex!\n");
        pthread_mutex_destroy(&buf->mutex);
        free(ptmp);
        return RINGBUF_ERROR_METUX;
    }
    if(pthread_cond_init(&buf->cond, NULL) != 0)
    {
        OUTPUT("[RINGBUF-ERROR]Failed to init cond!\n");
        pthread_mutex_destroy(&buf->mutex);
        pthread_mutex_destroy(&buf->cond_mutex);
        free(ptmp);
        return RINGBUF_ERROR_COND;
    }
    
    buf->pbuf         = ptmp;
    buf->capacity     = capacity;
    buf->pread_pos    = ptmp;
    buf->pwrite_pos   = ptmp;//读写指针在初始化时指向堆内存空间起始位置
    buf->used_space   = 0;
    buf->unused_space = capacity;
    buf->state        = RINGBUF_STAT_OK;
    
    buf->add_data          = add_data;
    buf->get_data_len      = get_data_len;
    buf->get_data_point    = get_data_point;
    buf->update_data_point = update_data_point;
    buf->wait_for_data     = wait_for_data;
    buf->switch_to_disable = switch_to_disable;
    buf->switch_to_enable  = switch_to_enable;
    buf->clear             = clear;
    buf->get_used_space    = get_used_space;
    buf->get_unused_space  = get_unused_space;
    
    return RINGBUF_SUCCESS;
}

//+------------------------------------------------------------------------------------------+
//|  函数名称：ring_buffer_destroy
//|  功能描述：销毁一个缓冲区对象结构，释放其在堆上申请的内存空间
//|  参数说明：指向缓冲区对象结构的指针
//|  返回值说明：成功返回RINGBUF_SUCCESS
//|  备注：应用程序需谨慎检查销毁的时机（一般为程序退出时）
//+------------------------------------------------------------------------------------------+
int ring_buffer_destroy(ST_RING_BUFFER *buf)
{
    /* 目标缓冲区状态检查 */
    if(buf == NULL)
    {
        OUTPUT("[RINGBUF-ERROR]Pointer is NULL!\n");
        return RINGBUF_ERROR_ILLEGAL_PARAM;
    }
    if(buf->state != RINGBUF_STAT_OK && 
       buf->state != RINGBUF_STAT_DISABILED)
    {
        OUTPUT("[RINGBUF-ERROR]The current state[%d] does not support operation[destroy]!\n", buf->state);
        return RINGBUF_ERROR_UNEXPECT_STATE;
    }
    
    if(buf->state == RINGBUF_STAT_OK)
    {
        /* 禁用缓冲区 */
        // ----------------------------------------
        // [说明]这里禁用缓冲区的目的是防止因程序设
        //       计失误，缓冲区销毁时有其它线程使用
        //       缓冲区资源造成内存访问异常或段错误。
        // [建议]上层程序设计时，最好在销毁缓冲区前
        //       先禁用缓冲区。
        // ----------------------------------------
        switch_to_disable(buf);
    }
    
    /* 资源释放和去初始化 */
    if(buf->pbuf == NULL)
    {
        OUTPUT("[RINGBUF-WARNING]The heap pointer is NULL!\n");
    }
    else
    {
        free(buf->pbuf);
    }
    
    if(pthread_mutex_destroy(&buf->mutex) != 0)
    {
        OUTPUT("[RINGBUF-WARNING]Failed to destroy mutex!\n");
    }
    if(pthread_mutex_destroy(&buf->cond_mutex) != 0)
    {
        OUTPUT("[RINGBUF-WARNING]Failed to destroy cond_mutex!\n");
    }
    if(pthread_cond_destroy(&buf->cond) != 0)
    {
        OUTPUT("[RINGBUF-WARNING]Failed to destroy cond!\n");
    }
    
    memset(buf, 0, sizeof(ST_RING_BUFFER));
    
    return RINGBUF_SUCCESS;
}
